<?php

namespace common\behavior;

use common\model\DemandPoolReportModel;
use common\model\OriginalPlanNodeModel;
use common\model\PlanModel;
use common\model\TaskModel;
use common\model\TaskRelationTagModel;
use common\service\DemandPoolReportService;
use common\service\OriginalPlanNodeService;
use common\service\StatusService;

/**
 * 更新排期节点
 */
class UpdateOriginalPlanNodeBehavior
{

    public function run($params)
    {
        $type = $params['module_code'] ?? '';
        $linkId = $params['link_id'] ?? 0;
        $operate = $params['operate'] ?? '';
        //更新排期操作
        $planIsLock = $params['record']['data']['new']['is_lock'] ?? 0;
        //删除操作  link_id没有
        if ($operate == 'delete') {
            $list = $params['record']['data'] ?? [];
            $linkId = array_column($list, 'id');
        }

        if (empty($linkId)) {
            return 0;
        }

        switch ($type) {
            //需求单
            case 'review_feedback':
                //需求单 -- 批量新增排期 ---只有新增
                return OriginalPlanNodeService::getInstance()->addOriginalPlanNotes($linkId);
            //排期
            case 'plan':
                //删除排期
                if ($operate == 'delete') {
                    $this->delOriginalPlanNote($linkId, $type);
                    //删除排期--需求池统计
                    return $this->delDemandPoolReportByPlanIds($linkId);
                }
                //更新、新增排期
                return $this->saveOriginalPlanNoteByPlan($linkId, $planIsLock);
            //延期单 、 工单
            case 'delay_order':
                return OriginalPlanNodeService::getInstance()->saveOriginalPlanNoteByDelayOrder($linkId);
            default:
                return 0;
        }
    }

    /**
     * 获取阶段ID
     * @param int $taskId 任务ID
     * @return int|mixed
     */
    private function getTaskStageId(int $taskId)
    {
        if (empty($taskId)) {
            return 0;
        }
        //查询任务表task.json->task_sage_id
        $tInfo = model(TaskModel::class)
            ->field('JSON_UNQUOTE(JSON_EXTRACT(json,\'$.task_stage_id\')) as stage_id')
            ->where(['id' => $taskId])->find();

        return $tInfo['stage_id'] ?? 0;
    }

    /**
     * 保存排期节点--排期
     * @param int $linkId     排期ID
     * @param int $planIsLock 更新排期操作
     * @return int
     */
    private function saveOriginalPlanNoteByPlan(int $linkId, int $planIsLock = 0)
    {
        $info = model(PlanModel::class)
            ->where(['id' => $linkId])
            ->find();
        if (empty($info)) {
            return 0;
        }
        //全局排期--变动
        if ($info['scope'] == PlanModel::SCOPE_GLOBAL) {
            return DemandPoolReportService::getInstance()->syncDemandPoolByPlanId($linkId);
        }
        //获取阶段ID
        $stageId = $this->getTaskStageId($info['task_id']);
        if (empty($stageId)) {
            //return 0;
        }
        $info['stage_id'] = $stageId;


        //查询环节ID
        $trtList = model(TaskRelationTagModel::class)
            ->where(['task_id' => $info['task_id'], 'link_module_code' => ['in', ['show_step_category', 'step_category']]])
            ->field('link_id')
            ->select();

        //循环小环节  条数不多
        foreach ($trtList as $val) {
            $info['step_category_id'] = $val['link_id'];
            //保存原计划排期节点
            $this->saveOriginalPlanNote($info, $planIsLock);
        }
        return 1;
    }

    /**
     * 保存排期节点 数据
     * @param array $data       数据
     * @param int   $planIsLock 更新排期操作
     * @return int
     */
    private function saveOriginalPlanNote(array $data, int $planIsLock)
    {
        //没时间 类型 返回
        if (!isset($data['end_time']) || empty($data['id'])) {
            return 0;
        }

        //原计划排期--类型
        $planMap = [PlanModel::TYPE_MEETING, PlanModel::TYPE_REVIEW, PlanModel::TYPE_TO_DO];
        $type = in_array($data['type'], $planMap) ? OriginalPlanNodeModel::TYPE_STANDARD_PLAN : OriginalPlanNodeModel::TYPE_INNER_PLAN;

        //组装数据
        $modifyData = [
            'link_id' => $data['id'],
            'type' => $type,
            'tenant_id' => $data['tenant_id'] ?? request()->tenantId,
            'episode_id' => $data['entity_id'] ?? 0,
            'step_category_id' => $data['step_category_id'] ?? 0,
            'name' => $data['name'] ?? '',
            'project_id' => $data['project_id'] ?? 0,
            'stage_id' => $data['stage_id'] ?? 0,
            'created_by' => $data['created_by'] ?? 0,
        ];

        try {
            //更新排期----锁定操作
            if ($planIsLock) {
                //查询 --- 所有实体、任务
                list($taskIds, $entityIds) = OriginalPlanNodeService::getInstance()->getPlanAllTask($data);
                $modifyData['all_entity_ids'] = implode(',', $entityIds);
                $modifyData['all_task_ids'] = implode(',', $taskIds);
                //点了锁定才更新交付时间
                $modifyData['delivery_time'] = $data['end_time'];
                //更新--脚本执行状态
                $modifyData['status'] = 1;
                //第一次同步排期--就是T1
                $modifyData['stage'] = $this->getPlanNodeNextStage($data);
                //更新任务交付时间
                $this->saveTaskPlanDeliveryTime($taskIds, $data);
            }

            //新增  或  修改
            $orgModel = model(OriginalPlanNodeModel::class);
            //查询--T0排期节点
            $orgInfo = $orgModel->field('id,delivery_time')
                ->where(['stage' => OriginalPlanNodeModel::STAGE_DEFAULT, 'link_id' => $data['id'], 'step_category_id' => $data['step_category_id'], 'type' => $type])
                ->find();

            if ($orgInfo) {
                //交付时间变更了---排期取消锁定
                if ($orgInfo['delivery_time'] != $data['end_time'] && !$planIsLock) {
                    model(PlanModel::class)->where(['id' => $data['id']])->save(['is_lock' => 0]);
                }
                $modifyData['id'] = $orgInfo['id'];
                $orgModel->modifyItem($modifyData);

                //更新排期----才切割节点
                if ($planIsLock) {
                    //标准排期--根据任务清单--切割原计划节点
                    OriginalPlanNodeService::getInstance()->splitStandardPlanData($orgInfo['id']);
                    //根据任务工序ID 切割节点
                    OriginalPlanNodeService::getInstance()->splitOriginalPlanNodeByStepId(0, $data['id']);
                    //更新详细表
                    OriginalPlanNodeService::getInstance()->syncOriginalPlanNodeDetailByLinkId($data['id']);
                }
            } else {
                //创建了新排期节点---排期取消锁定
                $stage = $this->getPlanNodeNextStage($data);
                if ($stage > OriginalPlanNodeModel::STAGE_T1) {
                    model(PlanModel::class)->where(['id' => $data['id']])->save(['is_lock' => 0]);
                }
                $modifyData['delivery_time'] = $data['end_time'];
                $orgModel->addItem($modifyData);
            }
        } catch (\Exception $e) {
            trace('更新排期节点失败' . PHP_EOL . format_exception_info($e), 'ERR');
        }
        return 1;
    }

    /**
     * 所处阶段 T1 T2 T3
     * @param array $data 查询条件
     * @return int
     */
    private function getPlanNodeNextStage(array $data)
    {
        $orgModel = model(OriginalPlanNodeModel::class);
        //判断节点是否有已有排期T1
        $lastOrgNode = $orgModel->field('max(stage) as stage')
            ->where(['link_id' => $data['id'], 'step_category_id' => $data['step_category_id']])
            ->find();
        $stage = $lastOrgNode['stage'] ?? 0;

        return $stage + 1;
    }


    /**
     * 更新任务时间
     * @param array $taskIds 任务IDs
     * @param array $data    排期详情数据
     * @return void
     */
    private function saveTaskPlanDeliveryTime(array $taskIds, array $data)
    {
        if (empty($taskIds)) {
            return;
        }
        $taskModel = model(TaskModel::class);
        //任务完成状态
        $statusDone = StatusService::getInstance()->getTaskDoneStatus();

        //更新条件
        $condition = [];
        $condition['id'] = ['IN', $taskIds];
        $condition["json->>'$.task_status'"] = ['NEQ', $statusDone['id']];

        try {
            //会议,审核、代办排期--修改任务（一组一组） 时间差
            if (in_array($data['type'], [PlanModel::TYPE_MEETING, PlanModel::TYPE_REVIEW, PlanModel::TYPE_TO_DO])) {
                //查询排期任务
                $planTaskTime = $taskModel->where(['id' => $data['task_id']])->value('plan_delivery_time');
                $timeNum = $data['end_time'] - $planTaskTime;

                $taskModel->where($condition)->setInc('plan_delivery_time', $timeNum);
                $taskModel->where($condition)->setInc('plan_end_time', $timeNum);
            } else {
                $taskModel->where($condition)->save(['plan_delivery_time' => $data['end_time']]);
            }
        } catch (\Exception $e) {
            trace('更新排期节点失败' . PHP_EOL . format_exception_info($e), 'ERR');
        }
    }


    /**
     * 删除排期节点
     * @param $linkIds  关联ID
     * @param $type     类型
     * @return int
     */
    private function delOriginalPlanNote($linkIds, $type = 'plan')
    {
        $planTypeList = [];
        //排期
        if ($type == 'plan') {
            $planTypeList = [OriginalPlanNodeModel::TYPE_STANDARD_PLAN, OriginalPlanNodeModel::TYPE_INNER_PLAN];
        }
        if (empty($planTypeList)) {
            return 0;
        }
        //删除条件
        $condition = [];
        $condition['type'] = ['in', $planTypeList];
        if (is_array($linkIds)) {
            $condition['link_id'] = ['in', $linkIds];
        } else {
            $condition['link_id'] = $linkIds;
        }

        try {
            //删除节点
            model(OriginalPlanNodeModel::class)->where($condition)->delete();
        } catch (\Exception $e) {
            trace('删除节点失败' . PHP_EOL . format_exception_info($e), 'ERR');
        }
        return 1;
    }

    /**
     * 删除排期的需求池统计
     * @param $linkIds
     * @return int
     */
    private function delDemandPoolReportByPlanIds($linkIds)
    {
        //删除条件
        $condition = [];
        if (is_array($linkIds)) {
            $condition['link_id'] = ['in', $linkIds];
        } else {
            $condition['link_id'] = $linkIds;
        }
        try {
            //删除排期的需求池统计
            model(DemandPoolReportModel::class)->where($condition)->delete();
        } catch (\Exception $e) {
            trace('删除需求池统计失败' . PHP_EOL . format_exception_info($e), 'ERR');
        }
        return 1;
    }
}